﻿#region Copyright 
/*-------------------------------------------------------------------------
* 命名空间名称/文件名:    SSPivot.Authorization.Authorize/PermissionHandler 
* CLR版本:     4.0.30319.42000
* 机器名称:    DESKTOP-NHMLO8A
* 功 能：       N/A
* 类 名：       PermissionHandler
* 创建时间：  2025/5/24 10:53:43
* 版本号：      v1.0
* 创建人:        xulong
*-------------------------------------------------------------------------*/
#endregion
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using SSPivot.AspNetCore.Abstractions.User;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;

namespace SSPivot.Authorization.Authorize
{
    public abstract class PermissionHandler : AuthorizationHandler<PermissionRequirement>
    {
        protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
        {
            if (context.User.Identity is not null && context.User.Identity.IsAuthenticated && context.Resource is HttpContext httpContext)
            {
                //var authHeader = httpContext.Request.Headers[AccessTokenConsts.AuthorizationHeader].ToString();
                //if (authHeader != null)
                //{
                //    context.Succeed(requirement);
                //    return;
                //}

                var codes = httpContext.GetEndpoint()?.Metadata?.GetMetadata<PermissionAttribute>()?.Codes;
                if (codes is null || codes.Length == 0)
                {
                    context.Succeed(requirement);
                    return;
                }

                var userContext = httpContext.RequestServices.GetService<ICurrentUser>() ?? throw new NullReferenceException(nameof(ICurrentUser));
                var result = await CheckPermissions(userContext?.Roles, codes);
                if (result)
                {
                    context.Succeed(requirement);
                    return;
                }
            }
            context.Fail();
        }

        protected abstract Task<bool> CheckPermissions(string[] roles, string[] codes);
    }
}
